/*
 * Copyright (c) 2025 CAX Conversion Project
 */
package com.comac.ins.cax.utils;

import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yk
 * @desc 文件类型工具
 * @date 2024-06-18 17:09
 */
@Slf4j
public class FileUtils {

    private static final Map<String, String> FILE_TYPE_EXTENSIONS = new HashMap<>();

    static {
        FILE_TYPE_EXTENSIONS.put("STEP", ".step");
        FILE_TYPE_EXTENSIONS.put("OBJ", ".obj");
        FILE_TYPE_EXTENSIONS.put("BDF", ".bdf");
        FILE_TYPE_EXTENSIONS.put("INP", ".inp");
        FILE_TYPE_EXTENSIONS.put("OP2", ".op2");
        FILE_TYPE_EXTENSIONS.put("VTK", ".vtk");
    }

    /**
     * 验证文件扩展名
     *
     * @param fileType 文件类型
     * @param file     文件
     * @return boolean
     */
    public static boolean isValidFileTypeBySuffix(String fileType, MultipartFile file) {
        String fileName = file.getOriginalFilename();
        if (fileName == null) {
            return false;
        }

        String expectedSuffix = FILE_TYPE_EXTENSIONS.get(fileType.toUpperCase());
        return fileName.endsWith(expectedSuffix);
    }

    /**
     * 根据文件类型获取文件扩展名
     *
     * @param fileType 文件类型
     * @return 文件扩展名
     */
    public static String getFileTypeBySuffix(String fileType) {
        return FILE_TYPE_EXTENSIONS.get(fileType.toUpperCase());
    }

    /**
     * 根据文件名获取扩展名称
     *
     * @param fileName 文件名称
     * @return 扩展名
     */
    public static String getFileExt(String fileName) {
        int pos = fileName.lastIndexOf(".");
        if (pos > -1) {
            return fileName.substring(pos + 1).toLowerCase();
        }
        return "";
    }

    /**
     * 替换文件后缀名
     *
     * @param filePath     文件路径
     * @param newExtension 新后缀
     * @return 新文件路径
     */
    public static String changeFileExtension(String filePath, String newExtension) {
        int extensionIndex = filePath.lastIndexOf('.');
        if (extensionIndex == -1) {
            // 如果原始路径中没有点，则直接在末尾添加新后缀
            return filePath + "." + newExtension;
        } else {
            // 如果找到了点，则替换点及之后的部分为新后缀
            return filePath.substring(0, extensionIndex) + "." + newExtension;
        }
    }

    /**
     * 文件下载
     *
     * @param response response
     * @param filePath 文件路径
     * @param fileName 文件名称
     * @throws IOException 异常
     */
    public static void downloadFile(HttpServletResponse response, String filePath, String fileName) throws IOException {
        response.setContentType("application/octet-stream");
        // 设置Content-Disposition头，用于指示浏览器将以附件的形式下载文件，而不是显示在浏览器中
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

        // 读取文件并写入输出流
        File file = new File(filePath);
        if (file.exists()) {
            OutputStream out = null;
            try (FileInputStream fis = new FileInputStream(file)) {
                out = response.getOutputStream();

                byte[] buffer = new byte[1024];
                int len;
                while ((len = fis.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
            } finally {
                if (out != null) {
                    out.flush();
                    out.close();
                }
            }
        } else {
            throw new RuntimeException("文件下载失败！filePath：" + filePath);
        }
    }

    /**
     * 检查指定路径的文件是否是一个合法的 ZIP 文件
     *
     * @param filePath 文件路径
     * @return 如果是 ZIP 文件返回 true，否则 false
     */
    public static boolean isZipFile(String filePath) {
        if (filePath == null || filePath.isEmpty()) {
            return false;
        }

        Path path = Paths.get(filePath);
        if (!Files.isRegularFile(path)) {
            log.error("文件不存在或不是普通文件");
            return false;
        }

        try (FileInputStream fis = new FileInputStream(filePath)) {
            byte[] signature = new byte[4];
            int bytesRead = fis.read(signature);
            if (bytesRead != 4) {
                log.error("无法读取文件头部");
                return false;
            }

            // ZIP 文件魔数：50 4B 03 04
            if (signature[0] == 0x50 && signature[1] == 0x4B &&
                signature[2] == 0x03 && signature[3] == 0x04) {
                return true;
            } else {
                log.error("不是 ZIP 文件格式");
                return false;
            }
        } catch (IOException e) {
            log.error("读取文件出错: " + e.getMessage());
            return false;
        }
    }
}
